<p>This guide will walk you through creating a basic widget inside Trilium.
  By following these steps, you'll learn how to build a simple UI element
  that interacts with the user.</p>
<h3>Step 1: The Basic Widget Structure</h3>
<p>To start, we'll create the most basic widget possible. Here's a simple
  example:</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
    get position() { return 1; }
    get parentWidget() { return "left-pane"; }
    
    doRender() {
        this.$widget = $("");
        return this.$widget;
    }
}

module.exports = new MyWidget();</code></pre>
<p>To implement this widget:</p>
<ol>
  <li>Create a new <code>JS Frontend</code> note in Trilium and paste in the code
    above.</li>
  <li>Assign the <code>#widget</code>  <a href="#root/_help_zEY4DaJG4YT5">attribute</a> to
    the <a href="#root/_help_BFs8mudNFgCS">note</a>.</li>
  <li>Restart Trilium or reload the window.</li>
</ol>
<p>To verify that the widget is working, open the developer tools (<code>Cmd</code> + <code>Shift</code> + <code>I</code>)
  and run <code>document.querySelector("#my-widget")</code>. If the element
  is found, the widget is functioning correctly. If <code>undefined</code> is
  returned, double-check that the <a href="#root/_help_BFs8mudNFgCS">note</a> has
  the <code>#widget</code>  <a href="#root/_help_zEY4DaJG4YT5">attribute</a>.</p>
<h3>Step 2: Adding an UI Element</h3>
<p>Next, let's improve the widget by adding a button to it.</p><pre><code class="language-text-x-trilium-auto">const template = ``;

class MyWidget extends api.BasicWidget {
    get position() {return 1;}
    get parentWidget() {return "left-pane"}

    doRender() {
        this.$widget = $(template);
        return this.$widget;
    }
}

module.exports = new MyWidget();</code></pre>
<p>After making this change, reload Trilium. You should now see a button
  in the top-left corner of the left pane.</p>
<h3>Step 3: Styling the Widget</h3>
<p>To make the button more visually appealing and position it correctly,
  we'll apply some custom styling. Trilium includes <a href="https://boxicons.com">Box Icons</a>,
  which we'll use to replace the button text with an icon. For example the <code>bx bxs-magic-wand</code> icon.</p>
<p>Here's the updated template:</p><pre><code class="language-text-x-trilium-auto">const template = ``;</code></pre>
<p>Next, we'll adjust the button's position using CSS:</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
    get position() { return 1; }
    get parentWidget() { return "left-pane"; }
    
    doRender() {
        this.$widget = $(template);
        this.cssBlock(`#my-widget {
            position: absolute;
            bottom: 40px;
            left: 60px;
            z-index: 1;
        }`);
        return this.$widget;
    }
}

module.exports = new MyWidget();</code></pre>
<p>After reloading Trilium, the button should now appear at the bottom left
  of the left pane, alongside other action buttons.</p>
<h3>Step 4: Adding User Interaction</h3>
<p>Let’s make the button interactive by showing a message when it’s clicked.
  We'll use the <code>api.showMessage</code> method from the <a href="#root/_help_GLks18SNjxmC">Script API</a>.</p><pre><code class="language-text-x-trilium-auto">class MyWidget extends api.BasicWidget {
    get position() { return 1; }
    get parentWidget() { return "left-pane"; }
    
    doRender() {
        this.$widget = $(template);
        this.cssBlock(`#my-widget {
            position: absolute;
            bottom: 40px;
            left: 60px;
            z-index: 1;
        }`);
        this.$widget.find("button").on("click", () =&gt; api.showMessage("Hello World!"));
        return this.$widget;
    }
}

module.exports = new MyWidget();</code></pre>
<p>Reload the application one last time. When you click the button, a "Hello
  World!" message should appear, confirming that your widget is fully functional.</p>